[Chapter 5] 5.2 Using File Permissions
Author: Simson Garfinkel & Gene Spafford
Date: 1999-02-04T00:01:36Z

#

| Chapter 5 The UNIX Filesystem |

## 5.2 Using File Permissions

Because file permissions determine who can read and modify the information stored in your files, they are your primary method for protecting the data that you store on your UNIX system.

Consider the directory listing presented earlier in this chapter:

>     % ls -lF
>     total 161
>     -rw-r--r-- 1 sian     user        505 Feb  9 13:19 instructions
>     -rw-r--r-- 1 sian     user       3159 Feb  9 13:14 invoice
>     -rw-r--r-- 1 sian     user       6318 Feb  9 13:14 letter
>     -rw------- 1 sian     user      15897 Feb  9 13:20 more-stuff
>     -rw-r----- 1 sian     biochem    4320 Feb  9 13:20 notes
>     -rwxr-xr-x 1 sian     user     122880 Feb  9 13:26 stats*
>     -------r-x 1 sian     user     989987 Mar  6 08:13 weird-file
>     %

In this example, any user on the system can read the files instructions, invoice, letter, or stats because they all have the letter r in the "other" column of the permissions field. The file notes can be read only by user sian or by users who are in the biochem group. And only sian can read the information in the file more-stuff.

A more interesting set of permissions is present on weird-file. User sian owns the file but cannot access it. Members of group user also are not allowed access. However, any user except sian who is also not in the group user can read and execute the file. Some variant of these permissions are useful in some cases where you want to make a file readable or executable by others, but you don't want to accidentally overwrite or execute it yourself. If you are the owner of the file and the permissions deny you access, it does not matter if you are in the group, or if other bits are set to allow the access.

Of course, the superuser can read any file on the system, and anybody who knows Sian's password can log in as sian and read her files (including weird-file, if the permissions are changed first).

### 5.2.1 chmod: Changing a File's Permissions

You can change a file's permissions with the `chmod` command or the `chmod()` system call. You can change a file's permissions only if you are the file's owner. The one exception to this rule is the superuser: if you are logged in as superuser, you can change the permissions of any file.[12]

> [12] Any file that is not mounted using NFS, that is. See Chapter 20 for details.

In its simplest form, the `chmod` command lets you specify which of a file's permissions you wish to change. This usage is called symbolic mode. The symbolic form of the `chmod` command[13] has the form:

> [13] The UNIX kernel actually supports two system calls for changing a file's mode: `chmod()`, which changes the mode of a file, and `fchmod()`, which changes the mode of a file associated with an open file descriptor.

>     chmod [-Rfh] [agou][+-=][rwxXstugol] filelist

This command changes the permissions of filelist, which can be either a single file or a group of files. The letters agou specify whose privileges are being modified. You may provide none, one, or more, as shown in Table 5.5.

Table 5.5: Whose Privileges Are Being Modified?
Letter | Meaning
--- | ---
a | Modifies privileges for all users
g | Modifies group privileges
o | Modifies others' privileges
u | Modifies the owner's privileges

The symbols specify what is supposed to be done with the privilege. You must type only one symbol, as shown in Table 5.6.

Table 5.6: What to Do with Privilege
Symbol | Meaning
--- | ---
+ | Adds to the current privilege
- | Removes from the current privilege
= | Replaces the current privilege

The last letters specify which privilege is to be added, as shown in Table 5.7.

Table 5.7: What Privileges Are Being Changed?
Letter | Meaning
--- | ---
Options for all versions of UNIX
r | Read access
w | Write access
x | Execute access
s | SUID or SGID
t | Sticky bit[14]
Options for BSD-derived versions of UNIX only:
X | Sets execute only if the file is a directory or already has some other execute bit set.
u | Takes permissions from the user permissions.
g | Takes permissions from the group permissions.
o | Takes permissions from other permissions.
Options for System V-derived versions of UNIX only:
l | Enables mandatory locking on file.

> [14] On most systems, only the superuser can set the sticky bit on a non-directory filesystem entry.

If the `-R` option is specified for versions that support it, the `chmod` command runs recursively. If you specify a directory in filelist, that directory has its permission changed, as do all of the files contained in that directory. If the directory contains any subdirectories, the process is repeated.

If the `-f` option is specified for versions that support it, `chmod` does not report any errors encountered. This processing is sometimes useful in shell scripts if you don't know whether the filelist exists or not and if you don't want to generate an error message.

The `-h` option is specified in some systems to change how `chmod` works with symbolic links. If the `-h` option is specified and one of the arguments is a symbolic link, the permissions of the file or directory pointed to by the link are not changed.

The symbolic form of the `chmod` command is useful if you only want to add or remove a specific privilege from a file. For example, if Sian wanted to give everybody in her group write permission to the file notes, she could issue the command:

>     % ls -l notes
>     -rw-r--r-- 1 sian     biochem    4320 Feb  9 13:20 notes %
>     chmod g+w notes
>     % ls -l notes
>     -rw-rw-r-- 1 sian     biochem    4320 Feb  9 13:20 notes %

To change this file further so people who aren't in her group can't read it, she could use the command:

>     % chmod o-r notes
>     % ls -l notes
>     -rw-rw---- 1 sian     biochem    4320 Feb  9 13:20 notes
>     %

To change the permissions of the invoice file so nobody else on the system can read or write it, Sian could use the command:

>     % chmod go= invoice
>     % ls -l invoice
>     -rw------- 1 sian     user    4320 Feb  9 13:20 invoice
>     % date
>     Sun Feb 10 00:32:55 EST 1991
>     %

Notice that changing a file's permissions does not change its modification time (although it will alter the inode's ctime).

### 5.2.2 Changing a File's Permissions

You can also use the `chmod` command to set a file's permissions, without regard to the settings that existed before the command was executed. This format is called the absolute form of the `chmod` command.

The absolute form of `chmod` has the syntax:

>     % chmod [-Rfh] mode filelist

where options have the following meanings:

-R

  As described earlier

-f

  As described earlier

-h

  As described earlier

mode

  The mode to which you wish to set the file, expressed as an octal[15] value

  > [15] Octal means "base 8." Normally, we use base 10, which uses the digits 0, 1, 2, 3, 4, 5, 6, 7, 8, and 9. The octal system uses the digitals 0, 1, 2, 3, 4, 5, 6, and 7. If you are confused, don't be: for most purposes, you can pretend that the numbers are in decimal notation and never know the difference.

filelist

  The list of the files whose modes you wish to set

To use this form of the `chmod` command, you must calculate the octal value of the file permissions that you want. The next section describes how to do this.

### 5.2.3 Calculating Octal File Permissions

`chmod` allows you to specify a file's permissions with a four-digit octal number. You calculate the number by adding[16] the permissions. Use Table 5.8 to determine the octal number that corresponds to each file permission.

> [16] Technically, we are ORing the values together, but as there is no carry, it's the same as adding.

Table 5.8: Octal Numbers and Permissions
Octal Number | Permission
--- | ---
4000 | Set user ID on execution (SUID)
2000 | Set group ID on execution (SGID)
1000 | "Sticky bit"
0400 | Read by owner
0200 | Write by owner
0100 | Execute by owner
0040 | Read by group
0020 | Write by group
0010 | Execute by group
0004 | Read by other
0002 | Write by other
0001 | Execute by other

Thus, a file with the permissions "-rwxr-x---" has a mode of 0750, calculated as follows:

0400 Read by owner

0200 Write by owner

0100 Execute by owner

0040 Read by group

0010 Execute by group 0750 Result

Table 5.9 contains some common file permissions and their uses.

Table 5.9: Common File Permissions
Octal Number | File | Permission
--- | --- | ---
0755 | /bin/ls | Anybody can copy or run the program; the file's owner can modify it.
0711 | $HOME | Locks a user's home directory so that no other users on the system can display its contents, but allows other users to access files or subdirectories contained within the directory if they know the names of the files or directories.
0700 | $HOME | Locks a user's home directory so that no other users on the system can access its contents, or the contents of any subdirectory.
0600 | /usr/mail/$USER and other mailboxes | The user can read or write the contents of the mailbox, but no other users (except the superuser) may access it.
0644 | any file | The file's owner can read or modify the file; everybody else can only read it.
0664 | groupfile | The file's owner or anybody in the group can modify the file; everybody else can only read it.
0666 | writable | Anybody can read or modify the file.
0444 | readable | Anybody can read the file; only the superuser can modify it without changing the permissions.

### 5.2.4 Using Octal File Permissions

After you have calculated the octal file permission that you want, you can use the `chmod` command to set the permissions of files you own.

For example, to make all of the C language source files in a directory writable by the owner and readable by everybody else, type the command:

>     % chmod 644 *.c
>     % ls -l *.c
>     -rw-r--r-- 1 kevin     okisrc   28092 Aug  9 9:52 cdrom.c
>     -rw-r--r-- 1 kevin     okisrc    5496 Aug  9 9:52 cfs_subr.c
>     -rw-r--r-- 1 kevin     okisrc    5752 Aug  9 9:52 cfs_vfsops.c
>     -rw-r--r-- 1 kevin     okisrc   11998 Aug  9 9:53 cfs_vnodeops.c
>     -rw-r--r-- 1 kevin     okisrc    3031 Aug  9 9:53 load_unld.c
>     -rw-r--r-- 1 kevin     okisrc    1928 Aug  9 9:54 Unix_rw.c
>     -rw-r--r-- 1 kevin     okisrc     153 Aug  9 9:54 vers.c
>     %

To change the permissions of a file so it can be read or modified by anybody in your group, but can't be read or written by anybody else in the system, type the command:

>     % chmod 660 memberlist
>     % ls -l memberlist
>     -rw-rw---- 1 kevin    okisrc     153 Aug 10 8:32 memberlist

>     %

### 5.2.5 Access Control Lists[17]

> [17] This section is largely based on Æleen Frisch's Essential System Administration, Second Edition (O'Reilly & Associates, 1995), Chapter 6, and is used here with permission.

Some versions of UNIX support Access Control Lists, or ACLS. These are normally provided as an extension to standard UNIX file permission modes. With ACLS, you can specify additional access rights to each file and directory for many individual users rather than lumping them all into the category "other." You can also set different permissions for members of different groups. We think they are a wonderful feature, and something we will see more of in future years. Unfortunately, every vendor has implemented them differently, and this makes describing them somewhat complex.

ACLS offer a further refinement to the standard UNIX file permissions capabilities. ACLS enable you to specify file access for completely arbitrary subsets of users and/or groups. Both AIX and HP-UX provide access control lists. Solaris and Linux are supposed to have them in future releases. Also, the Open Software Foundation's Distributed Computing Environment has a form of ACLS.

For many purposes, ACLS are superior to the UNIX group mechanism for small collaborative projects. If Hana wants to give Miria - and only Miria - access to a particular file, Hana can modify the file's ACL to give Miria access. Without ACLS, Hana would have to go to the system administrator, have a new group created that contains both Hana and Miria (and only Hana and Miria) as group members, and then change the group of the file to the newly created group.

> NOTE: Because ACLS are not standard across UNIX versions, you should not expect them to work in a network filesystem environment. In particular, Sun plans to support ACLS through the use of private extensions to the NFS3 filesystem, rather than building ACLS into the specification. Therefore, be sure that anything you export via NFS is adequately protected by the default UNIX file permissions and ownership settings.

#### 5.2.5.1 AIX Access Control Lists

An AIX ACL contains these fields (the text in italics to the right describes the line contents):

>     attributes:		  Special modes like SUID.
>     base permissions		  Normal UNIX file modes:
>         owner(chavez): rw-		   User access.
>         group(chem): rw-		   Group access.
>         others: r--		   Other access.
>     extended permissions		  More specific permissions entries:
>         enabled		   Whether they're used or not.
>         specify  r-- u:harvey		   Permissions for user harvey.
>         deny     -w- g:organic		   Permissions for group organic.
>         permit   rw- u:hill, g:bio	 	   Permissions for user hill when in group bio.

The first line specifies any special attributes on the file (or directory). The possible attribute keywords are SETUID, SETGID, and SVTX (sticky bit is set). Multiple attributes are all placed on one line, separated by commas.

The next section of the ACL lists the base permissions for the file or directory. These correspond exactly to the UNIX file modes. Thus, for the file we"re looking at, the owner (who is chavez) has read and write access, members of the group chem (which is the group owner of the file) also have read and write access, and all others have read access.

The final section specifies extended permissions for the file: access information specified by user and group name. The first line in this section is either the word enabled or disabled, indicating whether the extended permissions that follow are actually used to determine file access or not. In our example, extended permissions are in use.

The rest of the lines in the ACL are access control entries (ACES), which have the following format:

>     operation  access-types  user-and-group-info

where the operation is one of the keywords permit, deny, or specify, which correspond to `chmod`'s +, -, and = operators, respectively. permit adds the specified permissions to the ones the user already has, based on the base permissions; deny takes away the specified access; and specify sets the access for the user to the listed value. The access-types are the same as those for normal UNIX file modes. The user-and-group-info consists of a user name (preceded by u:) or one or more group names (each preceded by g:) or both. Multiple items are separated by commas.

Let"s look again at the ACES in our sample ACL:

>     specify  r--     u:harvey
>     deny     r--     g:organic
>     permit   rw-     u:hill, g:bio

The first line grants read-only access to user harvey on this file. The second line removes read access for the organic group from whatever permissions a user in that group already has. The final line adds read and write access to user hill while group bio is part of the current group set. By default, the current group set is all of the groups to which the user belongs.

ACLS that specify a username and group are useful mostly for accounting purposes; the ACL shown earlier ensures that user hill has group bio active when working with this file. They are also useful if you add a user to a group on a temporary basis, ensuring that the added file access goes away if the user is later removed from the group. In the previous example, user hill would no longer have access to the file if she were removed from the bio group (unless, of course, the file's base permissions grant it to her).

If more than one item is included in the user-and-group-info, then all of the items must be true for the entry to be applied to a process (AND logic). For example, the first ACE below is applied only to users who "have both bio and chem in their group sets" (which is often equivalent to "are members of both the chem and bio groups"):

>     permit   rw-    g:chem, g:bio
>     permit   rw-    u:hill, g:chem, g:bio

The second ACE applies to user hill only when both groups are in the current group set. If you wanted to grant write access to anyone who was a member of either group chem or group bio, you would specify two separate entries:

>     permit   rw-    g:chem
>     permit   rw-    g:bio

At this point, you might wonder what happens when more than one entry applies. When a process requests access to a file with extended permissions, the permitted accesses from the base permissions and all applicable ACES - all ACES which match the user and group identity of the process - are combined via a union operation. The denied accesses from the base permissions and all applicable ACES are also combined. If the requested access is permitted and it is not denied, then it is granted. Thus, contradictions among ACES are resolved in the most conservative way: access is denied unless it is both permitted and not denied.

For example, consider the ACL below:

>     attributes:  base permissions
>         owner(chavez): rw-
>         group(chem): r--
>         others:         ---
>     extended permissions
>         enabled
>         specify         r--   u:stein
>         permit          rw-   g:organic, g:bio
>         deny            rwx   g:physics

Now suppose that the user stein, who is a member of both the organic and bio groups (and not a member of the chem group), wants write access to this file. The base permissions clearly grant stein no access at all to the file. The ACES in lines one and two of the extended permissions apply to stein. These ACES grant him read access (lines one and two) and write access (line two). They also deny him write and execute access (implicit in line one). Thus, stein will not be given write access because while the combined ACES do grant it to him, they also deny write access, and so the request will fail.

> NOTE: The base permissions on a file with an extended access control list may be changed with `chmod`'s symbolic mode, and any changes made in this way will be reflected in the base permissions section of the ACL. However, `chmod`'s numeric mode must not be used for files with extended permissions, because using it automatically disables them.

ACLS may be applied and modified with the acledit command. acledit retrieves the current ACL for the file specified as its argument and opens it for editing, using the text editor specified by the EDITOR environment variable. The use of this variable under AIX is different from its use in other UNIX systems.[18] For one thing, no default exists (most UNIX implementations use vi when EDITOR is unset). For another, AIX requires that the full pathname to the editor be supplied, rather than only the filename.[19]

> [18] As are many things in AIX.

> [19] E.g., /bin/vi, not vi.

Once in the editor, make any changes to the ACL that you wish. If you are adding extended permission ACES, be sure to change disabled to enabled in the first line of that section. When you are finished, exit from the editor normally. AIX will then print the message:

>     Should the modified ACL be applied? (y)

If you wish to discard your changes to the ACL, enter "n"; otherwise, you should enter a carriage return. AIX will then check the new ACL, and if it has no errors, apply it to the file. If there are errors in the ACL (misspelled keywords or usernames are the most common), you will be placed back in the editor where you can correct the errors and try again. AIX will put error messages like the following example at the bottom of the file, describing the errors it found:

>     * line number  9: unknown keyword: spceify
>     * line number 10: unknown user: chavze

You don't need to delete the error messages themselves from the ACL.

However, this is the slow way of applying an ACL. The `aclget` and `aclput` commands offer alternative ways to display and apply ACLS to files.

`aclget` takes a filename as its argument, and displays the corresponding ACL on standard output (or to the file specified in its `-o` option).

The `aclput` command is used to read an ACL from a text file. By default, it takes its input from standard input, or from an input file specified with the -i option. Thus, to set the ACL for the file gold to the one stored in the file metal.acl, you could use this command:

>     $ aclput -i metal.acl gold

This form of aclput is useful if you use only a few different ACLS, all of which are saved as separate files to be applied as needed.

To copy an ACL from one file to another, put `aclget` and `aclput` together in a pipe. For example, the command below copies the ACL from the file silver to the file emerald:

>     $ aclget silver | aclput emerald

To copy an ACL from one file to a group of files, use `xargs`:

>     $ ls *.dat *.old | xargs -i /bin/sh -c "aclget silver | aclput {}"

These commands copy the ACL in silver to all the files ending in .dat and .old in the current directory.

You can use the `ls -le` command to quickly determine whether a file has an extended permissions set or not:

>     $ ls -le *_acl
>     -rw-r-----+   1 chavez  chem           51 Mar 20 13:27  has_acl
>     -rwxrws----   2 chavez  chem          512 Feb 08 17:58  no_acl

The plus sign appended to the normal mode string indicates the presence of extended permissions; the minus sign is present otherwise.

#### 5.2.5.2 HP-UX access control lists

The `lsacl` command can be used to view the access control list for a file. For a file having only normal UNIX file modes set, the output looks like this:

>     (chavez.%,rw-)(%.chem,r--)(%.%,---)  bronze

This example shows the format an ACL takes under HP-UX. Each parenthesized item is known as an access control list entry, although we're going to call them "entries." The percent sign character ("%") is a wildcard within an entry, and the three entries in the previous listing specify the access for user chavez as a member of any group, for any user in group chem, and for all other users and groups, respectively.

A file can have up to 16 access control list entries: three base entries corresponding to normal file modes and up to 13 optional entries. Here is the access control list for another file (generated this time by lsacl -l):

>     silver:
>     rwx chavez.%
>     r-x %.chem
>     r-x %.phys
>     r-x hill.bio
>     rwx harvey.%
>     --- %.%

This ACL grants every access to user chavez with any current group membership (she is the file owner). It grants read and execute access to members of the chem and phys groups; it grants read and execute access to user hill, if hill is a member of group bio; it grants user harvey read, write, and execute access regardless of his group membership; and it grants no access to any other user or group.

Entries within an HP-UX access control list are examined in order of decreasing specificity: entries with a specific user and group are considered first; those with only a specific user follow; ones with only a specific group are next; and the other entries are last of all. Within a class, entries are examined in order. When determining whether or not to permit file access, the first applicable entry is used. Thus, user harvey will be given write access to the file silver even if he is a member of the chem or phys group.

The `chacl` command is used to modify the access control list for a file. ACLS can be specified to `chacl` in two distinct forms: as a list of entries or via a `chmod`-like syntax. By default, `chacl` adds entries to the current ACL. For example, these two commands add to the file server's ACL read access for the bio group and read and execute access for user hill:

>     $ chacl "(%.bio,r--) (hill.%,r-x)" silver
>     $ chacl "%.bio = r, hill.% = rx" silver

In either format, the access control list must be passed to `chacl` as a single argument. The second format also includes + and - operators as in `chmod`. For example, this command adds read access for group chem and user harvey, and removes write access for group chem, adding or modifying ACL entries as needed:

>     $ chacl "%.chem -w+r, harvey.% +r" silver

chacl's -r option can be used to replace the current ACL:

>     $ chacl -r "@.% = 7, %.@ = rx, %.bio = r, %.% = " *.dat

The @ sign is a shorthand for the current user or group owner as appropriate, and also enables user-independent ACLS to be constructed. `chacl`'s -f option can be used to copy an ACL from one file to another file or group of files. This command applies the ACL from the file silver to all files in the current directory having the extension .dat :

>     $ chacl -f silver *.dat

Be careful with this option as it will change the ownership of target files if necessary so that the ACL exactly matches that of the specified file. If you merely want to apply a standard ACL to a set of files, you're better off creating a file containing the desired ACL, using @ characters as appropriate, and then applying it to files in this way:

>     $ chacl -r `cat acl.metal` *.dat

You can create the initial template file by using `lsacl` on an existing file and capturing the output.

You can still use `chmod` to change the base entries of a file with an ACL if you include the -A option. Files with optional entries are marked by a plus sign appended to the mode string in long directory listings:

>     -rw-------+  1 chavez   chem        8684 Jun 20 16:08 has_one
>     -rw-r--r--   1 chavez   chem      648205 Jun 20 11:12 none_here

5.1 Files |  | 5.3 The umask